function _isBridgeReady() {
	_JS_BRIDGE = _JS_BRIDGE || self[_JS_BRIDGE_NAME];
	return _JS_BRIDGE && _JS_BRIDGE.call
}
function _isSyncAPI(apiName) {
	return(/\w+Sync$/.test(apiName))
}
function _getStorageBusiness() {
	var href = self && self.location && self.location.href ? self.location.href : '';
	var business = href.replace(/^(http|https):\/\//i, '').split('/')[0];
	return business
}
function _fakeCallBack(cb, arg) {
	setTimeout(function() {
			cb(arg)
		},
		1)
}
function _isLocalId(localId) {
	return(/^[a-z0-9|]+$/i.test(localId))
}
function _fixOptData(opt, dataKey) {
	var objectArg = false;
	dataKey = dataKey || 'data';
	if(__hasOwnProperty(opt, '_')) {
		opt[dataKey] = opt._;
		delete opt._
	} else {
		__forEach(opt,
			function(key) {
				if(key !== dataKey) {
					objectArg = true
				}
			});
		if(objectArg) {
			objectArg = opt;
			opt = {};
			opt[dataKey] = objectArg
		}
	}
	return opt
}
function _getSameHandlers(evt, cb, isRemoveCache) {
	var sameHandlers = false;
	var sameIndex;
	if(!__isUndefined(evt)) {
		if(!_CACHE.EVENTS) {
			_CACHE.EVENTS = {}
		}
		if(!_CACHE.EVENTS[evt]) {
			_CACHE.EVENTS[evt] = {
				callbacks: []
			}
		}
		if(!_CACHE.EVENTS[evt].callbacks) {
			_CACHE.EVENTS[evt].callbacks = []
		}
		_CACHE.EVENTS[evt].callbacks.forEach(function(item, i) {
			if(item.cb === cb) {
				sameHandlers = item;
				sameIndex = i
			}
		});
		if(isRemoveCache && __isNumber(sameIndex)) {
			_CACHE.EVENTS[evt].callbacks.splice(sameIndex, 1)
		}
	}
	return sameHandlers
}
function _cacheEventHandler(evt, cb, _cb, _cbSFC) {
	var sameCBs = _getSameHandlers(evt, cb);
	if(!sameCBs) {
		_CACHE.EVENTS[evt].callbacks.push({
			cb: cb,
			_cb: _cb,
			_cbSFC: _cbSFC
		})
	}
}
function _removeEventHandler(evt, cb) {
	var handlers = _getSameHandlers(evt, cb, true);
	if(!__isFunction(cb)) {
		_CACHE.EVENTS[evt].callbacks.forEach(function(item) {
			AP.off(evt, item._cb)
		});
		_CACHE.EVENTS[evt].callbacks = []
	} else if(handlers) {
		AP.off(evt, handlers._cb)
	}
}
function _getApiOnEvent(apiName) {
	return _getApiEvent('on', apiName)
}
function _getApiOffEvent(apiName) {
	return _getApiEvent('off', apiName)
}
function _getApiEvent(prefix, apiName) {
	var jsapi = _JSAPI[apiName];
	var evt = false;
	var evtApiPattern = prefix === 'off' ? /^off([A-Z])(\w+)/ : /^on([A-Z])(\w+)/;
	if(jsapi && evtApiPattern.test(apiName)) {
		apiName = apiName.match(evtApiPattern);
		evt = jsapi.m;
		if(!evt && apiName[1] && apiName[2]) {
			evt = __tlc(apiName[1]) + apiName[2]
		}
	}
	return evt
}
function _getApiExtra(apiName, extraKey) {
	var jsapi = _JSAPI[apiName] || {};
	var extra = jsapi.e || {};
	return extra[extraKey]
}
function _getApiName(apiName) {
	var jsapi = _JSAPI[apiName];
	return jsapi && jsapi.m ? jsapi.m : apiName
}
function _getApiOption(apiName, opt, cb) {
	var jsapi = _JSAPI[apiName];
	var finalOpt = jsapi && jsapi.b ? jsapi.b(__extend({},
		opt), cb) : opt;
	var modifier = _getApiExtra(apiName, 'optionModifier');
	if(__isFunction(modifier)) {
		var modifyOpt = modifier(finalOpt);
		if(__isObject(modifyOpt)) {
			finalOpt = modifyOpt
		}
	}
	return finalOpt
}
function _getApiCallBacks(apiName, opt) {
	var cb = {};
	opt = opt || {};
	if(__isFunction(opt.success)) {
		cb.success = opt.success;
		delete opt.success
	}
	if(__isFunction(opt.fail)) {
		cb.fail = opt.fail;
		delete opt.fail
	}
	if(__isFunction(opt.complete)) {
		cb.complete = opt.complete;
		delete opt.complete
	}
	return cb
}
function _getApiDoing(apiName) {
	var jsapi = _JSAPI[apiName];
	return jsapi && jsapi.d ? jsapi.d : false
}
function _getApiResult(apiName, res, _opt, opt, cb) {
	var jsapi = _JSAPI[apiName];
	var finalRes = jsapi && jsapi.a ? jsapi.a(__isEvent(res) ? res : __extend({},
		res), _opt, opt, cb) : __extend({},
		res);
	var modifier = _getApiExtra(apiName, 'resultModifier');
	if(__isFunction(modifier)) {
		var modifyOpt = modifier(finalRes);
		if(__isObject(modifyOpt)) {
			finalRes = modifyOpt
		}
	}
	return finalRes
}
function _handleApiError(apiName, res) {
	if(__hasOwnProperty(res, 'error')) {
		res.error = parseInt(res.error, 10)
	}
	if(_getApiExtra(apiName, 'handleResultSuccess') !== false) {
		_handleResultSuccess(res)
	}
	if(res.error === 0) {
		delete res.error;
		delete res.errorMessage
	}
	if(res.error > 0 && res.error < 10) {
		console.error(apiName, res)
	}
	return res
}
function _handleResultSuccess(res, mappingError, successValue) {
	successValue = __isUndefined(successValue) ? false : successValue;
	if(!__hasOwnProperty(res, 'error') && res.success === successValue) {
		res.error = __isNumber(mappingError) ? mappingError : 2
	}
	delete res.success;
	return res
}
function _handleEventData(evtObj) {
	var data = {};
	if(!__isUndefined(evtObj.data)) {
		data = evtObj.data;
		data = __isObject(data) ? data : {
			data: data
		}
	}
	return data
}
function _separateTypeKey(key) {
	var matches = (key || '').match(/(\w+)(%\w)$/i);
	var tk = {
		k: key
	};
	if(matches) {
		tk.k = matches[1];
		tk.t = matches[2]
	}
	return tk
}
function _toType(type, value) {
	if(type === '%s') value = __superToString(value);
	if(type === '%c') value = __h2dColor(value);
	if(type === '%b') value = __removeBase64Head(value);
	if(type === '%d') value = parseInt(value, 10);
	if(type === '%f') value = parseFloat(value);
	return value
}
function _mapping(tObj, map, sObj) {
	var typeKey;
	sObj = sObj || {};
	__forEach(map,
		function(sKey, tKey) {
			typeKey = _separateTypeKey(map[sKey]);
			tKey = typeKey.k;
			if(!__isUndefined(tKey) && (__hasOwnProperty(tObj, sKey) || __hasOwnProperty(sObj, sKey)) && __isUndefined(tObj[tKey])) {
				tObj[tKey] = _toType(typeKey.t, __isUndefined(sObj[sKey]) ? tObj[sKey] : sObj[sKey]);
				if(tKey !== sKey) {
					delete tObj[sKey]
				}
			}
		});
	return tObj
}
var _apiRemoteLog = function() {
	var apiInvokeQueue = [];
	var timeoutId = void 0;
	function triggerSendLog() {
		setTimeout(function() {
				if(apiInvokeQueue.length > 0) {
					_JS_BRIDGE.call('remoteLog', {
						type: 'monitor',
						bizType: 'ALIPAYJSAPI',
						logLevel: 3,
						actionId: 'MonitorReport',
						seedId: 'ALIPAYJSAPI_INVOKE_COUNTER',
						param1: apiInvokeQueue.join('|')
					});
					AP.debug && console.info('API_INVOKE_QUEUE>', apiInvokeQueue);
					apiInvokeQueue = []
				}
			},
			0)
	}
	return function(apiName) {
		apiInvokeQueue.push(apiName);
		!__isUndefined(timeoutId) && clearTimeout(timeoutId);
		if(apiInvokeQueue.length >= 10) {
			triggerSendLog()
		} else {
			timeoutId = setTimeout(triggerSendLog, 5000)
		}
	}
}();
function _apiLog() {
	var apiName;
	var opt;
	var _opt;
	var res;
	var _res;
	var logs;
	if(AP.debug) {
		apiName = arguments.length <= 0 ? undefined : arguments[0];
		opt = arguments.length <= 1 ? undefined : arguments[1];
		_opt = arguments.length <= 2 ? undefined : arguments[2];
		res = arguments.length <= 3 ? undefined : arguments[3];
		_res = arguments.length <= 4 ? undefined : arguments[4];
		logs = [arguments.length > 3 ? 'RETURN>' : 'INVOKE>', apiName, __hasOwnProperty(opt, '_') ? opt._ : opt, _opt];
		if(arguments.length > 3) {
			logs.push(res)
		}
		if(arguments.length > 4) {
			logs.push(_res)
		}
		console.info(logs)
	}
}
function __inUA(keyPattern) {
	return keyPattern.test(_UA)
}
var __raf = function() {
	return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.msRequestAnimationFrame ||
		function(callback, element) {
			window.setTimeout(function() {
					callback(+new Date(), element)
				},
				1000 / 60)
		}
}();
function __isSupportPromise() {
	var isSupport = false;
	var P = self.Promise;
	if(P) {
		var promise = null;
		var then = null;
		try {
			promise = P.resolve();
			then = promise.then
		} catch(e) {}
		if(promise instanceof P && __isFunction(then) && !P.cast) {
			isSupport = true
		}
	}
	if(!isSupport) {
		console.warn('当前浏览器不支持 Promise，你仍然可以通过回调方式使用 AlipayJSAPI。')
	}
	return isSupport
}
function __superToString(content) {
	var str = content;
	if(__isObject(content) || __isArray(content)) {
		str = JSON.stringify(content)
	} else {
		str = content + ''
	}
	return str
}
function __h2dColor(hex) {
	var dec = '' + hex;
	if(dec.indexOf('#') === 0) {
		dec = dec.substr(1)
	}
	if(dec.length === 3) {
		dec = dec.replace(/(.)/g, '$1$1')
	}
	dec = parseInt(dec, 16);
	if(__isNaN(dec)) {
		console.error(hex + ' is invalid hex color.')
	}
	return dec
}
function __addBase64Head(base64, mimeType) {
	if(base64 && mimeType) {
		base64 = 'data:' + mimeType + ';base64,' + base64
	}
	return base64
}
function __removeBase64Head(base64) {
	if(__isString(base64)) {
		base64 = base64.replace(/^data:(\/|\w|\-|\.)+;base64,/i, '')
	}
	return base64
}
function __toQueryString(data) {
	var result = [];
	__forEach(data,
		function(key, value) {
			result.push(key + '=' + encodeURIComponent(__isUndefined(value) ? '' : value))
		});
	result = result.join('&');
	return result
}
function __buildUrl(url, params) {
	var qs = params;
	if(__isObject(params)) {
		qs = __toQueryString(params)
	}
	if(!/\?/.test(url)) {
		qs = '?' + qs
	} else if(!/&$/.test(url) && !/\?$/.test(url)) {
		qs = '&' + qs
	}
	return url + qs
}
function __hasOwnProperty(obj, key) {
	if(__isObject(obj) || __isArray(obj)) {
		return obj.hasOwnProperty(key)
	}
	return false
}
function __forEach(obj, cb) {
	var i;
	var key;
	if(__likeArray(obj)) {
		for(i = 0; i < obj.length; i++) {
			if(cb(i, obj[i]) === false) {
				return obj
			}
		}
	} else {
		for(key in obj) {
			if(cb(key, obj[key]) === false) {
				return obj
			}
		}
	}
	return obj
}
function __parseJSON(str) {
	try {
		str = JSON.parse(str)
	} catch(err) {
		console.warn(err, str)
	}
	return str
}
function __tlc(str) {
	if(__isString(str)) {
		str = str.toLowerCase()
	}
	return str
}
function __tuc(str) {
	if(__isString(str)) {
		str = str.toUpperCase()
	}
	return str
}
function __isAndroid() {
	return __inUA(/android/i)
}
function __isIOS() {
	return __inUA(/iPad|iPod|iPhone|iOS/i)
}
function __isUndefined(o) {
	return __type(o) === 'undefined'
}
function __isNull(o) {
	return __type(o) === 'null'
}
function __isNaN(num) {
	return parseInt(num, 10).toString() === 'NaN'
}
function __isBoolean(val) {
	return __type(val) === 'boolean'
}
function __isFunction(fn) {
	return __type(fn) === 'function'
}
function __isString(str) {
	return __type(str) === 'string'
}
function __isObject(o) {
	return __type(o) === 'object'
}
function __isNumber(num) {
	return __type(num) === 'number'
}
function __isArray(arr) {
	return __type(arr) === 'array'
}
function __likeArray(obj) {
	return !!obj && !__isFunction(obj) && (__isArray(obj) || __isNumber(obj.length))
}
function __isEvent(evt) {
	return __type(evt) === 'event'
}
function __type(obj) {
	return Object.prototype.toString.call(obj).replace(/\[object (\w+)\]/, '$1').toLowerCase()
}
function __isEmptyObject(obj) {
	for(var name in obj) {
		return false
	}
	return true
}
function __extend(obj) {
	var source;
	var prop;
	if(!__isObject(obj)) {
		return obj
	}
	for(var _len5 = arguments.length,
			args = Array(_len5 > 1 ? _len5 - 1 : 0), _key5 = 1; _key5 < _len5; _key5++) {
		args[_key5 - 1] = arguments[_key5]
	}
	for(var i = 0,
			length = args.length; i < length; i++) {
		source = args[i];
		for(prop in source) {
			if(hasOwnProperty.call(source, prop)) {
				obj[prop] = source[prop]
			}
		}
	}
	return obj
}

var _JS_BRIDGE_NAME = 'AlipayJSBridge';
var _JS_BRIDGE;
var _UA = navigator.userAgent;
var _MEDIA_BUSINESS = 'apm-h5';
var _IS_SUPPORT_PROMISE = __isSupportPromise();
var _WAITING_QUEUE = [];
var _CACHE = {
	getBAPSI: {
		isListening: false,
		lastState: 2,
		on: function on() {
			if(!_CACHE.getBAPSI.isListening) {
				_JS_BRIDGE.call('startMonitorBackgroundAudio');
				_CACHE.getBAPSI.isListening = true;
				AP.on('getBackgroundAudioPlayedStateInfo', _CACHE.getBAPSI.listener)
			}
		},
		off: function off() {
			AP.off('getBackgroundAudioPlayedStateInfo', _CACHE.getBAPSI.listener);
			_JS_BRIDGE.call('stopMonitorBackgroundAudio');
			_CACHE.getBAPSI.isListening = false
		},
		listener: function listener(evt) {
			var data = evt.data || {};
			var state = data.status;
			var triggerEvent;
			switch(state) {
				case 0:
					triggerEvent = 'backgroundAudioPause';
					break;
				case 1:
					triggerEvent = 'backgroundAudioPlay';
					break;
				case 2:
					triggerEvent = 'backgroundAudioStop';
					break;
				default:
					triggerEvent = undefined
			}
			if(triggerEvent && state !== _CACHE.getBAPSI.lastState) {
				AP.trigger(triggerEvent);
				_CACHE.getBAPSI.lastState = state
			}
		}
	}
};
var AP = {
	version: '3.0.3',
	ua: _UA,
	isAlipay: __inUA(/AlipayClient/),
	alipayVersion: function() {
		var version = _UA.match(/AlipayClient[a-zA-Z]*\/(\d+(?:\.\d+)+)/);
		return version && version.length ? version[1] : ''
	}(),
	compareVersion: function compareVersion(targetVersion) {
		var alipayVersion = AP.alipayVersion.split('.');
		targetVersion = targetVersion.split('.');
		for(var i = 0,
				n1, n2; i < alipayVersion.length; i++) {
			n1 = parseInt(targetVersion[i], 10) || 0;
			n2 = parseInt(alipayVersion[i], 10) || 0;
			if(n1 > n2) return -1;
			if(n1 < n2) return 1
		}
		return 0
	},
	parseQueryString: function parseQueryString(queryString) {
		var result = {};
		var searchStr = queryString || window.location.search;
		var bool = {
			true: true,
			false: false
		};
		var kv;
		searchStr = searchStr.indexOf('?') === 0 ? searchStr.substr(1) : searchStr;
		searchStr = searchStr ? searchStr.split('&') : '';
		for(var i = 0; i < searchStr.length; i++) {
			kv = searchStr[i].split('=');
			kv[1] = decodeURIComponent(kv[1]);
			kv[1] = __isUndefined(bool[kv[1]]) ? kv[1] : bool[kv[1]];
			result[kv[0]] = kv[1]
		}
		_apiRemoteLog('parseQueryString');
		return result
	},
	enableDebug: function enableDebug() {
		AP.debug = true
	},
	on: function on(evts, fn) {
		evts = evts.replace(/ready/, _JS_BRIDGE_NAME + 'Ready');
		evts.split(/\s+/g).forEach(function(eventName) {
			document.addEventListener(eventName, fn, false)
		})
	},
	off: function off(evt, fn) {
		document.removeEventListener(evt, fn, false)
	},
	trigger: function trigger(evtName, data) {
		var evt = document.createEvent('Events');
		evt.initEvent(evtName, false, true);
		evt.data = data || {};
		document.dispatchEvent(evt);
		return evt
	}
};
